﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace ParkingLot.Utility
{
    public class InstanceHelp<T>
    {
        private Dictionary<string, FieldInfo> m_DictField=new Dictionary<string, FieldInfo>();

        private Dictionary<string,PropertyInfo> m_DictProperty=new Dictionary<string, PropertyInfo>(); 

        public InstanceHelp()
        {
            Type type = typeof (T);
            FieldInfo[] fieldInfos =
                type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance |
                               BindingFlags.Static);

            foreach (FieldInfo fieldInfo in fieldInfos)
            {
                m_DictField.Add(fieldInfo.Name,fieldInfo);
            }

            PropertyInfo[] propertyInfos =
                type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance |
                                   BindingFlags.Static);

            foreach (PropertyInfo propertyInfo in propertyInfos)
            {
                m_DictProperty.Add(propertyInfo.Name, propertyInfo);
            }
        }

        /// <summary>
        /// 根据属性名称设置值(需要Get,Set访问器)
        /// </summary>
        /// <typeparam name="F"></typeparam>
        /// <param name="t"></param>
        /// <param name="propertyName">属性名称</param>
        /// <param name="value"></param>
        public  void SetPropertyByName<F>(T t, string propertyName, F value)
        {
            //DateTime dtTime=DateTime.Now;
            if (m_DictProperty.ContainsKey(propertyName) == false)
            {
                return;
            }
            PropertyInfo field = m_DictProperty[propertyName];
            if (field != null)
            {
                field.SetValue(t, value);
            }
            //TimeSpan TS = DateTime.Now - dtTime;
            //Debug.WriteLine("赋值时间" + TS.TotalMilliseconds);
        }

        /// <summary>
        /// 根据字段名称设置值(字段 无需属性无需Get,Set)
        /// </summary>
        /// <typeparam name="F"></typeparam>
        /// <param name="t"></param>
        /// <param name="fileName"></param>
        /// <param name="value"></param>
        public void SetFieldByName<F>(T t, string fileName, F value)
        {
            //DateTime dtTime=DateTime.Now;
            if (m_DictField.ContainsKey(fileName) == false)
            {
                return;
            }
            FieldInfo field = m_DictField[fileName];
            if (field != null)
            {
                field.SetValue(t, value);
            }
            //TimeSpan TS = DateTime.Now - dtTime;
            //Debug.WriteLine("赋值时间" + TS.TotalMilliseconds);
        }

        [Obsolete("不怎么好用")]
        public void SetProperty<F>(T t, string propertyName, F value)
        {
            if (m_DictProperty.ContainsKey(propertyName) == false)
            {
                return;
            }

            PropertyInfo propertyInfo = m_DictProperty[propertyName];

            SetValueDelegate setter2 = DynamicMethodFactory.CreatePropertySetter(propertyInfo);
            setter2(t, value);
        }
    }
}
